import { TIMES } from '@/config';
import { clickByBounds, clickByDesc } from '@/utils/clickManager';
import LogManager from '@/utils/LogManager';
import orRegular from '@/utils/orRegular';
import SettingsManager from '@config/settings';
import Application from './Application';

/**
 * getter 装饰器
 * 判断参与福袋按钮是否存在，不存在则展示出来
 */
function isParticipate(target: any, propertyName: string, descriptor: PropertyDescriptor) {
  if (descriptor.get) {
    const originGetter = descriptor.get;
    descriptor.get = function () {
      const _this = this as Fudai;
      if (!_this.participateNode) {
        clickByBounds(_this.openNode);
        sleep(TIMES.FUDAI_SLEEP_SHORT);
      }
      return originGetter.apply(this);
    };
  } else {
    console.error(`Property ${propertyName} does not have a getter method`);
  }
}

class Fudai {
  /** 参与状态 */
  private status = false;
  private openNodeTimeoutCount = 0;

  readonly openNodeMatch = /超级福袋.*按钮|福袋.*按钮|福袋，.*/;
  readonly participateNodeMatch = /一键发表评论|去发表评论|参与抽奖|参与成功 等待开奖|加入粉丝团|活动已结束/;
  readonly resultNodeMatch = /知道了|我知道了|立即领取奖励/;
  readonly describeNodeMatch = orRegular([
    ' 后开奖',
    '.*人已参与',
    '参考价值: ¥.*',
    '参与任务',
    '发送评论：.*',
    '未达成',
    '已达成',
    '参与成功 等待开奖',
    '请勿离开直播间，否则抽奖资格失效',
    '加入购物粉丝团',
    '加入粉丝团',
    '活动已结束',
    '¥',
    ' :',
    '一键发表评论',
    '参与抽奖',
    '参与成功 等待开奖',
    '加入粉丝团',
    '活动已结束',
    '共.*份',
  ]);

  readonly favoredDescribeMatch = /手机|iPhone|苹果|OPPO|红米|Readmi|VIVO|HUAWEI|荣耀|小米|iQOO|真我|联想|三星|平板|iPad|苹|果|128|type-c|Apple/;

  private log(value: any) {
    LogManager.add(`[Fudai]\t${value}`);
  }

  getStatus() {
    return this.status;
  }

  setStatus(bool: boolean) {
    this.status = bool;
    this.log(`修改参与状态: ${bool}`);
  }

  resetState() {
    this.setStatus(false);
    this.openNodeTimeoutCount = 0;
  }

  /** 获取福袋节点超时计数 */
  getOpenNodeTimeoutCount(): number {
    return this.openNodeTimeoutCount;
  }
  setOpenNodeTimeoutCount(count: number) {
    this.openNodeTimeoutCount = count;
  }

  /**
   * 打开福袋按钮
   * 直播间左上角福袋图片
   */
  get openNode() {
    const node = textMatches(this.openNodeMatch).findOne(TIMES.FUDAI_FIND_NODE_TIMEOUT_SHORT);
    if (!node) {
      this.setOpenNodeTimeoutCount(this.openNodeTimeoutCount + 1);
      return null;
    }
    return textMatches(this.openNodeMatch).findOne(TIMES.FUDAI_FIND_NODE_TIMEOUT_SHORT);
  }

  /** 点击打开福袋按钮 */
  clickOpen(): void {
    if (this.participateNode) {
      this.log('open: 已经打开参与界面');
      return;
    }
    if (this.openNode) {
      this.log('open: 成功打开参与界面');
      clickByBounds(this.openNode);
    }
  }

  /**
   * 参与按钮
   * 参与|已参与|加入粉丝团|活动已结束
   */
  get participateNode() {
    let node = textMatches(this.participateNodeMatch).findOne(TIMES.FUDAI_FIND_NODE_TIMEOUT_SHORT);

    // 这里为了解决频繁点击 福袋
    /* if (this.openNode) {
      clickByBounds(this.openNode);
      sleep(TIMES.FUDAI_SLEEP_SHORT);
      node = textMatches(this.participateNodeMatch).findOne(TIMES.FUDAI_FIND_NODE_TIMEOUT_SHORT);
    } */

    return node;
  }

  /** 点击参与按钮 */
  clickParticipate(): void {
    const text = this.participateNode?.text();

    switch (text) {
      case '一键发表评论':
      case '参与抽奖':
        clickByBounds(this.participateNode);
        this.log('成功参与福袋');
        this.setStatus(true);
        break;
      case '去发表评论':
        clickByBounds(this.participateNode);
        sleep(TIMES.FUDAI_SLEEP_SHORT);
        clickByDesc('发送');
        this.setStatus(true);
        break;

      case '参与成功 等待开奖':
        sleep(TIMES.FUDAI_SLEEP_SHORT);
        this.log('参与成功 等待开奖');
        this.setStatus(true);
        back();
        break;

      case '活动已结束':
        back();
        sleep(TIMES.FUDAI_SLEEP_SHORT);
        this.setStatus(false);
        break;

      case '加入粉丝团':
        clickByBounds(this.participateNode);
        sleep(TIMES.FUDAI_SLEEP_SHORT);
        clickByBounds(this.participateNode);
        sleep(TIMES.FUDAI_SLEEP_SHORT);
        back();
        sleep(TIMES.FUDAI_SLEEP_LONE);
        this.clickOpen();
        sleep(TIMES.FUDAI_SLEEP_SHORT);
        this.clickParticipate();
        break;
    }
  }

  /**
   * 结果按钮
   * 我知道了|立即领取奖励
   */
  get resultNode() {
    return textMatches(this.resultNodeMatch).findOne(TIMES.FUDAI_FIND_NODE_TIMEOUT_SHORT);
  }

  /** 结果处理 */
  clickResult(): void {
    const text = this.resultNode?.text();

    switch (text) {
      case '知道了':
      case '我知道了':
        this.log('福袋已结束，未中奖');
        clickByBounds(this.resultNode);
        this.setStatus(false);
        break;

      case '立即领取奖励':
        this.log('福袋结束，已中奖');
        Application.playWinRingSound('http://music.163.com/song/media/outer/url?id=333750.mp3');
        break;
    }
  }

  /**
   * 倒计时时间
   * @returns 为 -1 打开福袋按钮不存在;
   */
  get countDown() {
    if (this.openNode) {
      const [, minute, second] = this.openNode
        .text()
        .split(' ')[1]
        .match(/(\d+)分(\d+)秒/)!;
      return [Number(minute), Number(second)];
    }

    return [-1, -1];
  }

  /** 参考价格 */
  @isParticipate
  get price() {
    // 未显示参与福袋按钮
    if (!this.participateNode) {
      clickByBounds(this.openNode);
      sleep(TIMES.FUDAI_SLEEP_SHORT);
    }

    const node = textMatches(/参考价值: ¥(.*)/).findOne(TIMES.FUDAI_FIND_NODE_TIMEOUT_SHORT);
    if (node) {
      const price = node.text().match(/参考价值: ¥(.*)/)![1];
      return Number(price);
    }

    return 0;
  }

  /** 福袋描述/标题 */
  @isParticipate
  get describe() {
    const nodeList = className('com.lynx.tasm.behavior.ui.text.FlattenUIText').drawingOrder(5).find();
    const node = nodeList.filter(item => {
      const text = item.text();
      if (!text.match(this.describeNodeMatch) && !text.match(/^\d{1,2}$/)) {
        return item;
      }
    });
    if (node.length === 0) return '';
    return node[0].text();
  }

  /** 是否满足心仪物品 */
  get isFavoredDescribe(): boolean {
    const settings = SettingsManager.getSettings();
    const { other, phone } = settings.prizeTypes;
    if (phone) {
      const isExits = this.describe.match(this.favoredDescribeMatch);
      this.log(`${isExits ? '是心仪的' + isExits[0] : '不是心仪的物品'}`);
      if (!isExits) return false;
      return Boolean(isExits);
    }

    return true;
  }
}

export default new Fudai();
